const MyPromise = require('./4.MyPromise.js');
const assert = require('assert');

// 同步resolve
let p1 = function () {
    return new MyPromise(function (resolve, reject) {
        resolve('success');
    })
};

p1().then(res => assert(res === 'success')).catch(e => console.log(e));

// 同步reject
let p2 = function () {
    return new MyPromise(function (resolve, reject) {
        reject('fail');
    })
};

p2().then(null, reason => assert(reason === 'fail')).catch(e => console.log(e));

// 异步resolve
let p3 = function () {
    return new MyPromise(function (resolve, reject) {
        setTimeout(() => {
            resolve('async-success')
        }, 0)
    })
};

p3().then(res => assert(res === 'async-success')).catch(e => console.log(e));

// then可选参数
p3().then().then().then(res => assert(res === 'async-success')).catch(e => console.log(e));

// then中返回promise
function other() {
    return new MyPromise((resolve, reject) => {
        resolve('other');
    })
}

let p4 = function () {
    return new MyPromise(function (resolve, reject) {
        resolve('success');
    })
};

p4().then(other).then(res => assert(res === 'other')).catch(e => console.log(e));

// 检查循环调用promise
let p6 = MyPromise.resolve(1).then((value) => {
    return p6
});

p6.then(null, (e) => assert(e.message === "Chaining cycle detected for promise #<Promise>"));

// 执行器抛出错误
let p7 = new MyPromise(() => {
    throw new TypeError('Executor Error');
});
p7.then(null, (e) => assert(e.message === 'Executor Error')).catch(e => console.log(e));

// Promise.all
let p8 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('p8');
    }, 0)
});

let p9 = MyPromise.resolve('p9');

let promises = [1, 2, p8, p9];
MyPromise.all(promises).then(results => assert.deepEqual(results, [1, 2, 'p8', 'p9'])).catch(e => console.log(e))

// Promise.race
let p10 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('p10');
    }, 10)
});
promises = [p8, p10];
MyPromise.race(promises).then(result => assert(result === 'p8')).catch(e => console.log(e));

// Promise.resolve(promise)
MyPromise.resolve(p8).then(res => assert(res === 'p8')).catch(e => console.log(e));
MyPromise.resolve('xx').then(res => assert(res === 'xx')).catch(e => console.log(e));

// Promise.allSettled
const p11 = MyPromise.resolve('p11');
const p12 = new MyPromise((resolve, reject) => setTimeout(() => reject('p12_reject'), 100));
promises = [p11, p12];

MyPromise.allSettled(promises).then((results) => assert.deepEqual(results, ['p11', 'p12_reject'])).catch(e => console.log(e));

// Promise finally
function p13() {
    return new MyPromise((resolve, reject) => {
        setTimeout(function () {
            reject('p13_reject')
        }, 0)
    })
}

MyPromise.resolve().finally(() => {
    return p13();
}).then(null, reason => assert(reason === 'p13_reject')).catch(e => console.log(e));
